
//#pragma once
#ifndef __ledmatrix_c__
#define __ledmatrix_c__

#include <zneo.h>

#include "ledmatrix.h"
#include "bitsformatted.h"
#include "ledmatrixglyphs.h"

void Blank(void) {
	PGOUT &= ~0x7F;
	PEOUT |=  0x1F;
}

void Latch(unsigned short i) {
	switch(i) {
		case 0: 
			PEOUT &= ~0xE0;
			PEOUT !=  0xE0;
			PGOUT &= ~0x80;
			PGOUT |=  0x80;
			break;
		case 1: 
			PEOUT &= ~0x80;
			PEOUT |=  0x80;
			break;
		case 2: 
			PGOUT &= ~0x80;
			PGOUT |=  0x80;
			break;
		case 3: 
			PEOUT &= ~0x20;
			PEOUT |=  0x20;
			break;
		case 4: 
			PEOUT &= ~0x40;
			PEOUT |=  0x40;
			break;
	}	
}

void InitLEDMatrixes(void) {
	PEOC = 0x00;
	PGOC = 0x00;

	PEDD = 0x00;
	PGDD = 0x00;

	InitGlyphs();
}

void ClearLEDMatrix(unsigned short i) {
	Blank();
	Latch(i);
}

void SetLEDMatrix(unsigned short i, char c) {
	Blank();
	PGOUT |= GetGlyphColumn(c,0);
	PEOUT &= ~0x10;
	Latch(i);
	Blank();
	PGOUT |= GetGlyphColumn(c,1);
	PEOUT &= ~0x08;
	Latch(i);
	Blank();
	PGOUT |= GetGlyphColumn(c,2);
	PEOUT &= ~0x04;
	Latch(i);
	Blank();
	PGOUT |= GetGlyphColumn(c,3);
	PEOUT &= ~0x02;
	Latch(i);
	Blank();
	PGOUT |= GetGlyphColumn(c,4);
	PEOUT &= ~0x01;
	Latch(i);

	// Latch an extra blank in to prevent uneven brightness
	Blank();
	Latch(i);
}

void DisplayString(char* phrase, unsigned int offset, unsigned int length)
{
	int i;
	for (i=0; i<4; ++i) {
		SetLEDMatrix(1+i, offset+i<length ? phrase[offset+i] : 'x');
	}
}

char volatile matrixbuffer[4];
unsigned short volatile col = 0;

void DrawMatrixBuffer(void) {
	short i;

	Blank();
	PEOUT = ~(0x10 >> col);
	for (i=0;i<4;++i) {
		PGOUT &= ~0x7F;
		PGOUT |= GetGlyphColumn(matrixbuffer[i], col);
		Latch(i+1);
	}
	col = (col+1)%5;
}

void SetMatrixBuffer(char *str) {
	int i, s=0;
	for(i=0;i<4;++i) {
		if (s==0 && str[i]) {
			matrixbuffer[i] = str[i];
		} else {
			s = 1;
			matrixbuffer[i] = ' ';
		}
	}
}

#define HEX(a) (a<10?'0'+a:'A'+(a-10))

void SetMatrixBufferHex(short i) {
	matrixbuffer[0] = ' ';
	matrixbuffer[1] = ' ';
	matrixbuffer[2] = HEX((i/16));
	matrixbuffer[3] = HEX((i&0x0F));
}

void SetMatrixBufferHex2(char m, short i) {
	matrixbuffer[0] = ' ';
	matrixbuffer[1] = m;
	matrixbuffer[2] = HEX((i/16));
	matrixbuffer[3] = HEX((i&0x0F));
}

#endif